/**
 * GenJ - GenealogyJ
 *
 * Copyright (C) 1997 - 2002 Nils Meier <nils@meiers.net>
 *
 * This piece of code is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This code is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
package genj.gedcom;

import java.util.List;

/**
 * Gedcom Property : CHIL The property wrapping the condition of having a child in a family
 */
public class PropertyChild extends PropertyXRef {

    private final static TagPath PATH_FAMCHIL = new TagPath("FAM:CHIL");

    /**
     * Empty Constructor
     */
    /* package */PropertyChild() {
	super("CHIL");
    }

    /**
     * need tag-argument constructor for all properties
     */
    /* package */PropertyChild(String tag) {
	super(tag);
	assertTag("CHIL");
    }

    /**
     * Returns the child
     * 
     * @return referenced child
     */
    public Indi getChild() {
	return (Indi) getTargetEntity();
    }

    /**
     * Returns a warning string that describes what happens when this property would be deleted
     * 
     * @return warning as <code>String</code>, <code>null</code> when no warning
     */
    @Override
    public String getDeleteVeto() {
	// warn if linked
	if (getTargetEntity() == null)
	    return null;
	return resources.getString("prop.chil.veto");
    }

    /**
     * Links reference to entity (if not already done)
     * 
     * @exception GedcomException
     *                when property has no parent property, referenced individual is child, wife or
     *                husband in enclosing family or it would become ancestor of itself by this
     *                action.
     */
    @Override
    public void link() throws GedcomException {

	// Get enclosing family ?
	Fam fam;
	try {
	    fam = (Fam) getEntity();
	} catch (ClassCastException ex) {
	    throw new GedcomException(resources.getString("error.noenclosingfam"));
	}

	// Prepare some VARs
	Property p;
	Property ps[];

	// Look for child (not-existing -> Gedcom throws Exception)
	Indi child = (Indi) getCandidate();

	// Make sure the child is not ancestor of family already (father, mother, grandfather,
	// grandgrandfather, ...)
	// .. that would introduce a circle
	if (child.isAncestorOf(fam))
	    throw new GedcomException(resources.getString("error.already.ancestor", child
		    .toString(), fam.toString()));

	// NM20070921 - see PropertyFamilyChild.link()

	// Connect back from child (maybe using back reference)
	List<PropertyFamilyChild> famcs = child.getProperties(PropertyFamilyChild.class);
	for (int i = 0, j = famcs.size(); i < j; i++) {

	    PropertyFamilyChild pfc = famcs.get(i);
	    if (pfc.isCandidate(fam)) {
		link(pfc);
		return;
	    }

	}

	// .. new back referencing property
	PropertyFamilyChild pfc = new PropertyFamilyChild();
	child.addProperty(pfc);
	link(pfc);

	// Done
    }

    /**
     * an externalized label we need in some ui actions
     */
    public static String getLabelChildAlreadyinFamily(Indi child, Fam fam) {
	return resources.getString("error.already.child", child.toString(), fam.toString());
    }

    /**
     * The expected referenced type
     */
    @Override
    public String getTargetType() {
	return Gedcom.INDI;
    }

} // PropertyChild
